package com.gateway.plugin.security.oauth2.authorization;

import com.gateway.common.dto.ApiDefinition;
import com.gateway.security.common.authentication.client.ClientAuthenticationToken;
import com.gateway.security.common.authentication.client.ClientPrincipal;
import com.gateway.security.common.authorization.AuthorizationChecker;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.core.Authentication;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * @program: api-gateway
 * @description:
 * @author: YuKai Fan
 * @create: 2025/2/11 22:54
 **/
public class ScopeAuthorizationChecker implements AuthorizationChecker {

    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, ServerWebExchange exchange, ApiDefinition apiDefinition) {
        return authentication.
                filter(Authentication::isAuthenticated)
                .cast(ClientAuthenticationToken.class)
                .map(ClientAuthenticationToken::getPrincipal)
                .cast(ClientPrincipal.class)
                .filter(Objects::nonNull)
                .map(ClientPrincipal::getAuthorities)
                .filter(authorities -> authorities.stream().anyMatch(authority -> authority.getAuthority().equals(apiDefinition.getApiCode())))
                .map(authorities -> new AuthorizationDecision(true))
                .defaultIfEmpty(new AuthorizationDecision(false));

    }
}
